package com.ls.security;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.Key;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;

/**
 * 
 * @ClassName: SimpleTest3
 * @Description: 基于口令的加密与解密
 * @author 我夕
 * @date 2012-5-16
 */
public class SecretWithPw {

	public static void main(String[] args) throws Exception {

		//直接在代码中进行加密与解密的方式
//		simpleSecret();
		byte[] salt = new byte[] { 0x7d, 0x60, 0x43, 0x5f, 0x02, (byte) 0xe9, (byte) 0xe0, (byte) 0xae };
		for(byte a : salt){
			System.out.println(a);
			
		}
	
		
		// 简单密钥加密2,将密钥写到磁盘
//		simpleSecret2();

	}

	/**
	 * 直接在代码中进行加密与解密的方式
	 */
	public static void simpleSecret() throws Exception {
		// PBEWithMD5AndDES是一个算法的名称，关于其他具体的算法名称大家可以查看文档
		Cipher cipher = Cipher.getInstance("PBEWithMD5AndDES");// 创建对象实例
		// SecretKeyFactory.getInstance("PBEWithMD5AndDES")中的参数必须与Cipher.getInstance("PBEWithMD5AndDES")相同
		// PBEKeySpec(char[] password) 长度必须为8个字节
		SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(new PBEKeySpec("libsslc".toCharArray()));
		// PBEParameterSpec 是PKCS #5 标准中所定义的基于密码的加密法构造一个参数集合
		PBEParameterSpec parameterSpec = new PBEParameterSpec(new byte[] { 1,2, 3, 4, 5, 6, 7, 8 }, 1000);
		cipher.init(Cipher.ENCRYPT_MODE, key, parameterSpec);
		// 初始化
		byte[] result = cipher.doFinal("hello java !".getBytes());
		System.out.println("加密后的数据："+new String(result));
		for(int i=0;i<100;i++){
			cipher.doFinal(("aa"+i).getBytes());
		}
		// 解密
		cipher.init(Cipher.DECRYPT_MODE, key, parameterSpec);
		
		System.out.println("解密后的数据："+new String(cipher.doFinal(result)));
	}

	/**
	 * 密钥数据写到磁盘的方式
	 */
	public static void simpleSecret2() throws Exception {

		// 密钥加密
		Cipher cipher = Cipher.getInstance("PBEWithMD5AndDES");// 创建对象实例
		SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(new PBEKeySpec("22345678".toCharArray()));

		// 将产生的密钥写到磁盘上
		FileOutputStream foskey = new FileOutputStream("myKey.key");
		ObjectOutputStream oos = new ObjectOutputStream(foskey);
		oos.writeObject(key);
		oos.close();
		foskey.close();

		PBEParameterSpec parameterSpec = new PBEParameterSpec(new byte[] { 1,2, 3, 4, 5, 6, 7, 8 }, 10);
		cipher.init(Cipher.ENCRYPT_MODE, key, parameterSpec);
		// 初始化
		byte[] result = cipher.doFinal("How are you !".getBytes());
		System.out.println("加密后的数据："+new String(result));

		// 将加密后的数据写到磁盘上
		FileOutputStream fosData = new FileOutputStream("myData.data");
		fosData.write(result);
		fosData.close();

		// **密钥解密*//
		simpleDecrypt();
	}

	// 密钥解密方法一
	public static void simpleDecrypt() throws Exception {

		// 从磁盘读进密钥
		FileInputStream fiskey = new FileInputStream("myKey.key");
		ObjectInputStream oiskey = new ObjectInputStream(fiskey);
		Key key = (Key) oiskey.readObject();
		oiskey.close();
		fiskey.close();

		// 从磁盘读进数据
		FileInputStream fisDat = new FileInputStream("myData.data");
		// 读二进制数据
		ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
		int len = 0;
		byte[] data = new byte[1024];
		while ((len = fisDat.read(data)) != -1) {
			arrayOutputStream.write(data, 0, len);
		}
		byte[] result = arrayOutputStream.toByteArray();
		arrayOutputStream.close();
		fisDat.close();

		Cipher cipher = Cipher.getInstance("PBEWithMD5AndDES");// 创建对象实例
		PBEParameterSpec parameterSpec = new PBEParameterSpec(new byte[] { 1,2, 3, 4, 5, 6, 7, 8 }, 10);
		cipher.init(Cipher.DECRYPT_MODE, key, parameterSpec);
		// 初始化
		byte[] data2 = cipher.doFinal(result);
		System.out.println("解密后的数据："+new String(data2));

	}

}

